home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-29 | 40.0 KB | 1,348 lines |
- Newsgroups: comp.sources.misc
- From: dvadura@plg.waterloo.edu (Dennis Vadura)
- Subject: v27i123: dmake - dmake Version 3.8, Part22/41
- Message-ID: <1992Jan28.214333.19336@sparky.imd.sterling.com>
- X-Md4-Signature: 0a2c3090e0f8f2dc24f4c6de875e7a74
- Date: Tue, 28 Jan 1992 21:43:33 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: dvadura@plg.waterloo.edu (Dennis Vadura)
- Posting-number: Volume 27, Issue 123
- Archive-name: dmake/part22
- Environment: Atari-ST, Coherent, Mac, MSDOS, OS/2, UNIX
- Supersedes: dmake: Volume 19, Issue 22-58
-
- ---- Cut Here and feed the following to sh ----
- # this is dmake.shar.22 (part 22 of a multipart archive)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file dmake/msdos/bccdos/public.h continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 22; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test -f _shar_wnt_.tmp; then
- sed 's/^X//' << 'SHAR_EOF' >> 'dmake/msdos/bccdos/public.h' &&
- --
- -- This program is free software; you can redistribute it and/or
- -- modify it under the terms of the GNU General Public License
- -- (version 1), as published by the Free Software Foundation, and
- -- found in the file 'LICENSE' included with this distribution.
- --
- -- This program is distributed in the hope that it will be useful,
- -- but WITHOUT ANY WARRANTY; without even the implied warrant of
- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- -- GNU General Public License for more details.
- --
- -- You should have received a copy of the GNU General Public License
- -- along with this program; if not, write to the Free Software
- -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- --
- -- LOG
- -- $Log$
- */
- X
- #ifndef _DMAKE_PUBLIC_h
- #define _DMAKE_PUBLIC_h
- X
- void Infer_recipe ANSI((CELLPTR, CELLPTR));
- int Make_targets ANSI(());
- int Exec_commands ANSI((CELLPTR));
- void Print_cmnd ANSI((char *, int, int));
- void Pop_dir ANSI((int));
- void Append_line ANSI((char *, int, FILE *, char *, int, int));
- void Stat_target ANSI((CELLPTR, int));
- char * Expand ANSI((char *));
- char * Apply_edit ANSI((char *, char *, char *, int, int));
- void Map_esc ANSI((char *));
- char* Apply_modifiers ANSI((int, char *));
- char* Tokenize ANSI((char *, char *));
- char * _strjoin ANSI((char *, char *, int, int));
- char * _stradd ANSI((char *, char *, int));
- char * _strapp ANSI((char *, char *));
- char * _strdup ANSI((char *));
- char * _strdup2 ANSI((char *));
- char * _strpbrk ANSI((char *, char *));
- char * _strspn ANSI((char *, char *));
- char * _strstr ANSI((char *, char *));
- char * _substr ANSI((char *, char *));
- uint16 Hash ANSI((char *, uint32 *));
- HASHPTR Get_name ANSI((char *, HASHPTR *, int));
- HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *));
- HASHPTR Def_macro ANSI((char *, char *, int));
- CELLPTR Def_cell ANSI((char *));
- LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int));
- void Clear_prerequisites ANSI((CELLPTR));
- int Test_circle ANSI((CELLPTR, int));
- STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int));
- t_attr Rcp_attribute ANSI((char *));
- int main ANSI((int, char **));
- FILE * Openfile ANSI((char *, int, int));
- FILE * Closefile ANSI(());
- FILE * Search_file ANSI((char *, char **));
- char * Filename ANSI(());
- int Nestlevel ANSI(());
- void No_ram ANSI(());
- int Usage ANSI((int));
- int Version ANSI(());
- char * Get_suffix ANSI((char *));
- char * Build_path ANSI((char *, char *));
- void Make_rules ANSI(());
- void Create_macro_vars ANSI(());
- time_t Do_stat ANSI((char *, char *, char **));
- int Do_touch ANSI((char *, char *, char **));
- void Void_lib_cache ANSI((char *, char *));
- time_t Do_time ANSI(());
- int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int));
- char ** Pack_argv ANSI((int, int, char *));
- char * Read_env_string ANSI((char *));
- int Write_env_string ANSI((char *, char *));
- void ReadEnvironment ANSI(());
- void Catch_signals ANSI((void (*)()));
- void Clear_signals ANSI(());
- void Prolog ANSI((int, char* []));
- void Epilog ANSI((int));
- char * Get_current_dir ANSI(());
- int Set_dir ANSI((char*));
- char Get_switch_char ANSI(());
- FILE* Get_temp ANSI((char **, char *, int));
- FILE * Start_temp ANSI((char *, CELLPTR, char **));
- void Open_temp_error ANSI((char *, char *));
- void Link_temp ANSI((CELLPTR, FILE *, char *));
- void Close_temp ANSI((CELLPTR, FILE *));
- void Unlink_temp_files ANSI((CELLPTR));
- void Handle_result ANSI((int, int, int, CELLPTR));
- void Update_time_stamp ANSI((CELLPTR));
- int Remove_file ANSI((char *));
- void Parse ANSI((FILE *));
- int Get_line ANSI((char *, FILE *));
- char * Do_comment ANSI((char *, char **, int));
- char * Get_token ANSI((TKSTRPTR, char *, int));
- void Quit ANSI(());
- void Read_state ANSI(());
- void Write_state ANSI(());
- int Check_state ANSI((CELLPTR, STRINGPTR *, int));
- char* basename ANSI((char *));
- void Dump ANSI(());
- void Dump_recipe ANSI((STRINGPTR));
- int Parse_macro ANSI((char *, int));
- int Macro_op ANSI((char *));
- int Parse_rule_def ANSI((int *));
- int Rule_op ANSI((char *));
- void Add_recipe_to_list ANSI((char *, int, int));
- void Bind_rules_to_targets ANSI((int));
- int Set_group_attributes ANSI((char *));
- DFALINKPTR Match_dfa ANSI((char *));
- void Check_circle_dfa ANSI(());
- void Add_nfa ANSI((char *));
- char * Exec_function ANSI((char *));
- int If_root_path ANSI((char *));
- int runargv ANSI((CELLPTR, int, int, int, int, char *));
- void Clean_up_processes ANSI(());
- int Wait_for_child ANSI((int, int));
- time_t seek_arch ANSI((char*, char*));
- int touch_arch ANSI((char*, char*));
- int _chdir ANSI((char *));
- void Remove_prq ANSI((CELLPTR));
- void Hook_std_writes ANSI((char *));
- X
- #endif
- SHAR_EOF
- chmod 0640 dmake/msdos/bccdos/public.h ||
- echo 'restore of dmake/msdos/bccdos/public.h failed'
- Wc_c="`wc -c < 'dmake/msdos/bccdos/public.h'`"
- test 5547 -eq "$Wc_c" ||
- echo 'dmake/msdos/bccdos/public.h: original size 5547, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/msdos/bccdos/startup.mk ==============
- if test -f 'dmake/msdos/bccdos/startup.mk' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/msdos/bccdos/startup.mk (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/msdos/bccdos/startup.mk' &&
- # MSDOS DMAKE startup file. Customize to suit your needs.
- # Assumes MKS toolkit for the tool commands, and Turbo-C. Change as req'd.
- # See the documentation for a description of internally defined macros.
- #
- # Disable warnings for macros redefined here that were given
- # on the command line.
- __.SILENT := $(.SILENT)
- .SILENT := yes
- X
- # Configuration parameters for DMAKE startup.mk file
- # Set these to NON-NULL if you wish to turn the parameter on.
- _HAVE_RCS := yes # yes => RCS is installed.
- _HAVE_SCCS := # yes => SCCS is installed.
- X
- # Applicable suffix definitions
- A := .lib # Libraries
- E := .exe # Executables
- F := .for # Fortran
- O := .obj # Objects
- P := .pas # Pascal
- S := .asm # Assembler sources
- V := # RCS suffix
- X
- # See if these are defined
- TMPDIR := $(ROOTDIR)/tmp
- .IMPORT .IGNORE : TMPDIR SHELL COMSPEC
- X
- # Recipe execution configurations
- # First set SHELL, If it is not defined, use COMSPEC, otherwise
- # it is assumed to be MKS Korn SHELL.
- .IF $(SHELL) == $(NULL)
- .IF $(COMSPEC) == $(NULL)
- X SHELL := $(ROOTDIR)/bin/sh$E
- .ELSE
- X SHELL := $(COMSPEC)
- .END
- .END
- GROUPSHELL := $(SHELL)
- X
- # Now set remaining arguments depending on which SHELL we
- # are going to use. COMSPEC (assumed to be command.com) or
- # MKS Korn Shell.
- .IF $(SHELL)==$(COMSPEC)
- X SHELLFLAGS := $(SWITCHAR)c
- X GROUPFLAGS := $(SHELLFLAGS)
- X SHELLMETAS := *"?<>
- X GROUPSUFFIX := .bat
- X DIRSEPSTR := \\
- X DIVFILE = $(TMPFILE:s,/,\)
- .ELSE
- X SHELLFLAGS := -c
- X GROUPFLAGS :=
- X SHELLMETAS := *"?<>|()&][$$\#`'
- X GROUPSUFFIX := .ksh
- X .MKSARGS := yes
- X DIVFILE = $(TMPFILE:s,/,${DIVSEP_shell_${USESHELL}})
- X DIVSEP_shell_yes := \\\
- X DIVSEP_shell_no := \\
- .END
- X
- # Standard C-language command names and flags
- X CC := bcc # C-compiler and flags
- X CFLAGS +=
- X
- X AS := tasm # Assembler and flags
- X ASFLAGS +=
- X
- X LD = tlink # Loader and flags
- X LDFLAGS +=
- X LDLIBS =
- X
- # Definition of $(MAKE) macro for recursive makes.
- X MAKE = $(MAKECMD) $(MFLAGS)
- X
- # Language and Parser generation Tools and their flags
- X YACC := yacc # standard yacc
- X YFLAGS +=
- X YTAB := ytab # yacc output files name stem.
- X
- X LEX := lex # standard lex
- X LFLAGS +=
- X LEXYY := lex_yy # lex output file
- X
- # Other Compilers, Tools and their flags
- X PC := tpc # pascal compiler
- X RC := anyf77 # ratfor compiler
- X FC := anyf77 # fortran compiler
- X
- X CO := co # check out for RCS
- X COFLAGS += -q
- X
- X AR := ar # archiver
- X ARFLAGS+= ruv
- X
- X RM := rm # remove a file command
- X RMFLAGS +=
- X
- # Implicit generation rules for making inferences.
- # We don't provide .yr or .ye rules here. They're obsolete.
- # Rules for making *$O
- X %$O .SWAP: %.c ; $(CC) $(CFLAGS) -c $<
- X %$O .SWAP: %$P ; $(PC) $(PFLAGS) -c $<
- X %$O .SWAP: %$S ; $(AS) $(ASFLAGS) $(<:s,/,\);
- X %$O : %.cl ; class -c $<
- X %$O .SWAP: %.e %.r %.F %$F ; $(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<
- X
- # Executables
- X %$E .SWAP: %$O ; $(CC) $(LDFLAGS) -e$@ $<
- X
- # lex and yacc rules
- X %.c .SWAP: %.y ; $(YACC) $(YFLAGS) $<; mv $(YTAB).c $@
- X %.c .SWAP: %.l ; $(LEX) $(LFLAGS) $<; mv $(LEXYY).c $@
- X
- # RCS support
- .IF $(_HAVE_RCS)
- X % : $$(@:d)RCS/$$(@:f)$V;- $(CO) $(COFLAGS) $@
- X .NOINFER : $$(@:d)RCS/$$(@:f)$V
- .END
- X
- # SCCS support
- .IF $(_HAVE_SCCS)
- X % : s.% ; get $<
- X .NOINFER : s.%
- .END
- X
- # Recipe to make archive files.
- %$A .SWAP:
- [
- X $(AR) $(ARFLAGS) $@ $?
- X $(RM) $(RMFLAGS) $?
- ]
- X
- # DMAKE uses this recipe to remove intermediate targets
- .REMOVE :; $(RM) -f $<
- X
- # AUGMAKE extensions for SYSV compatibility
- @B = $(@:b)
- @D = $(@:d)
- @F = $(@:f)
- "*B" = $(*:b)
- "*D" = $(*:d)
- "*F" = $(*:f)
- <B = $(<:b)
- <D = $(<:d)
- <F = $(<:f)
- ?B = $(?:b)
- ?F = $(?:f)
- ?D = $(?:d)
- X
- # Turn warnings back to previous setting.
- .SILENT := $(__.SILENT)
- X
- # Local init file if any, gets parsed before user makefile
- .INCLUDE .IGNORE: "_startup.mk"
- SHAR_EOF
- chmod 0640 dmake/msdos/bccdos/startup.mk ||
- echo 'restore of dmake/msdos/bccdos/startup.mk failed'
- Wc_c="`wc -c < 'dmake/msdos/bccdos/startup.mk'`"
- test 3831 -eq "$Wc_c" ||
- echo 'dmake/msdos/bccdos/startup.mk: original size 3831, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/msdos/bccdos/tempnam.c ==============
- if test -f 'dmake/msdos/bccdos/tempnam.c' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/msdos/bccdos/tempnam.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/msdos/bccdos/tempnam.c' &&
- /*LINTLIBRARY*/
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <dos.h>
- X
- #if defined(max)
- # undef max
- #endif
- #define max(A,B) (((A)<(B))?(B):(A))
- X
- extern char *mktemp();
- extern int access();
- int _access();
- X
- /* Turbo C stdio.h doesn't define P_tmpdir, so let's do it here */
- /* Under DOS leave the default tmpdir pointing here! */
- static char *P_tmpdir = "";
- X
- char *
- tempnam(dir, prefix)
- char *dir; /* use this directory please (if non-NULL) */
- char *prefix; /* use this (if non-NULL) as filename prefix */
- {
- X static int count = 0;
- X register char *p, *q, *tmpdir;
- X int tl=0, dl=0, pl;
- X char buf[30];
- X
- X pl = strlen(P_tmpdir);
- X
- X if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir);
- X if( dir != NULL ) dl = strlen(dir);
- X
- X if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL )
- X return(NULL);
- X
- X *p = '\0';
- X
- X if( (tl == 0) || (_access( strcpy(p, tmpdir), 0) != 0) )
- X if( (dl == 0) || (_access( strcpy(p, dir), 0) != 0) )
- X if( _access( strcpy(p, P_tmpdir), 0) != 0 )
- X if( !prefix )
- X prefix = "tp";
- X
- X if(prefix)
- X {
- X *(p+strlen(p)+2) = '\0';
- X (void)strncat(p, prefix, 2);
- X }
- X
- X sprintf( buf, "%08x", _psp );
- X buf[6]='\0';
- X (void)strcat(p, buf );
- X sprintf( buf, "%04d", count++ );
- X q=p+strlen(p)-6;
- X *q++ = buf[0]; *q++ = buf[1];
- X *q++ = buf[2]; *q++ = buf[3];
- X
- X if( (q = strrchr(p,'.')) != NULL ) *q = '\0';
- X
- X return(p);
- }
- X
- X
- X
- _access( name, flag )
- char *name;
- int flag;
- {
- X char *p;
- X int r;
- X
- X if( name == NULL || !*name ) return(1); /* NULL dir means current dir */
- X r = access( name, flag );
- X p = name+strlen(name)-1;
- X if(*p != '/' && *p != '\\') strcat( p, "/" );
- X
- X return( r );
- }
- SHAR_EOF
- chmod 0640 dmake/msdos/bccdos/tempnam.c ||
- echo 'restore of dmake/msdos/bccdos/tempnam.c failed'
- Wc_c="`wc -c < 'dmake/msdos/bccdos/tempnam.c'`"
- test 1724 -eq "$Wc_c" ||
- echo 'dmake/msdos/bccdos/tempnam.c: original size 1724, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/msdos/bccdos/utime.c ==============
- if test -f 'dmake/msdos/bccdos/utime.c' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/msdos/bccdos/utime.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/msdos/bccdos/utime.c' &&
- /*
- ** change access and modify times of file
- */
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <time.h>
- X
- int
- utime(name, timep)/*
- ====================
- X Broken for turbo C it only sets the file time to the current time by
- X touching a character in the file */
- char* name;
- time_t timep[2];
- {
- X struct stat buf;
- X int fil;
- X char data;
- X
- X if (stat(name, &buf) != 0)
- X return (-1);
- X if (buf.st_size != 0) {
- X if ((fil = open(name, O_RDWR, S_IWRITE)) < 0)
- X return (-1);
- X if (read(fil, &data, 1) < 1) {
- X close(fil);
- X return (-1);
- X }
- X lseek(fil, 0L, 0);
- X if (write(fil, &data, 1) < 1) {
- X close(fil);
- X return (-1);
- X }
- X close(fil);
- X return (0);
- X } else if ((fil = creat(name, S_IWRITE)) < 0) {
- X return (-1);
- X } else {
- X close(fil);
- X return (0);
- X }
- }
- SHAR_EOF
- chmod 0640 dmake/msdos/bccdos/utime.c ||
- echo 'restore of dmake/msdos/bccdos/utime.c failed'
- Wc_c="`wc -c < 'dmake/msdos/bccdos/utime.c'`"
- test 767 -eq "$Wc_c" ||
- echo 'dmake/msdos/bccdos/utime.c: original size 767, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/msdos/config.mk ==============
- if test -f 'dmake/msdos/config.mk' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/msdos/config.mk (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/msdos/config.mk' &&
- # This is an OS specific configuration file
- # It assumes that OBJDIR, TARGET and DEBUG are previously defined.
- # It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS
- # It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS
- #
- X
- # Memory model to compile for
- # set to s - small, m - medium, c - compact, l - large
- # Need large model now, dmake has grown up :-)
- MODEL = l
- X
- STARTUPFILE = $(OS)/startup.mk
- X
- CPPFLAGS = $(CFLAGS)
- LDOBJS = $(CSTARTUP) $(OBJDIR)/{$(<:f)}
- LDARGS = $(LDHEAD) @$(LDTMPOBJ),$(TARGET),NUL.MAP$(LDTAIL)
- LDTAIL = $(_libs)$(LDFLAGS:s/ //)
- _libs = $(!null,$(LDLIBS) ,@$(LDTMPLIB))
- LDTMPOBJ = $(mktmp,,$(DIVFILE) $(LDOBJS:s,/,\\,:t"+\n")\n)
- LDTMPLIB = $(mktmp,,$(DIVFILE) $(LDLIBS:s,/,\\,:t"+\n")\n)
- X
- # Debug flags
- DB_CFLAGS = -DDBUG
- DB_LDFLAGS =
- DB_LDLIBS =
- X
- # NO Debug flags
- NDB_CFLAGS =
- NDB_LDFLAGS =
- NDB_LDLIBS =
- X
- # Local configuration modifications for CFLAGS.
- CFLAGS += -I$(OS)
- X
- # Common MSDOS source files.
- # Define SWAP to anything but 'y' for the swap code to be excluded on making.
- # Swapping for DOS versions is enabled by default.
- # Note: swapping is handled specially for ZTC in msdos/ztcdos/config.mk.
- SWAP *= y
- .IF $(OSRELEASE) != ztcdos
- X .IF $(SWAP) == y
- X SWP_SRC = find.c spawn.c
- X ASRC += exec.asm
- X .ELSE
- X SWP_SRC = tee.c
- X .END
- .ELSE
- X SWP_SRC = tee.c
- .END
- X
- OS_SRC += ruletab.c dirbrk.c runargv.c arlib.c _chdir.c switchar.c rmprq.c\
- X $(SWP_SRC)
- SRC += $(OS_SRC)
- .SETDIR=$(OS) : $(ASRC) $(OS_SRC)
- X
- # Provide our own %$O : %$S rule.
- %$O : %$S
- X $(AS) $(ASFLAGS) $(<:s,/,\,);
- X mv $(@:f) $(OBJDIR)
- X
- # Set source dirs so that we can find files named in this
- # config file.
- .SOURCE.h : $(OS)
- X
- # See if we modify anything in the lower levels.
- .IF $(OSRELEASE) != $(NULL)
- X .INCLUDE .IGNORE : $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)config.mk
- .END
- SHAR_EOF
- chmod 0640 dmake/msdos/config.mk ||
- echo 'restore of dmake/msdos/config.mk failed'
- Wc_c="`wc -c < 'dmake/msdos/config.mk'`"
- test 1821 -eq "$Wc_c" ||
- echo 'dmake/msdos/config.mk: original size 1821, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/msdos/dirbrk.c ==============
- if test -f 'dmake/msdos/dirbrk.c' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/msdos/dirbrk.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/msdos/dirbrk.c' &&
- /* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/msdos/dirbrk.c,v 1.1 1992/01/24 03:27:29 dvadura Exp $
- -- SYNOPSIS -- define the directory separator string.
- --
- -- DESCRIPTION
- -- Define this string for any character that may appear in a path name
- -- and can be used as a directory separator.
- --
- -- AUTHOR
- -- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- -- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- --
- -- COPYRIGHT
- -- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- --
- -- This program is free software; you can redistribute it and/or
- -- modify it under the terms of the GNU General Public License
- -- (version 1), as published by the Free Software Foundation, and
- -- found in the file 'LICENSE' included with this distribution.
- --
- -- This program is distributed in the hope that it will be useful,
- -- but WITHOUT ANY WARRANTY; without even the implied warrant of
- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- -- GNU General Public License for more details.
- --
- -- You should have received a copy of the GNU General Public License
- -- along with this program; if not, write to the Free Software
- -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- --
- -- LOG
- -- $Log: dirbrk.c,v $
- X * Revision 1.1 1992/01/24 03:27:29 dvadura
- X * dmake Version 3.8, Initial revision
- X *
- */
- X
- #include "extern.h"
- X
- /* dos uses /, \, and : */
- char* DirBrkStr = "/\\:";
- X
- /*
- ** Return TRUE if the name is the full specification of a path name to a file
- ** starting at the root of the file system, otherwise return FALSE
- */
- PUBLIC int
- If_root_path(name)
- char *name;
- {
- X return( (strchr(DirBrkStr, *name) != NIL(char)) ||
- X (isalpha(*name) && name[1] == ':') );
- }
- SHAR_EOF
- chmod 0640 dmake/msdos/dirbrk.c ||
- echo 'restore of dmake/msdos/dirbrk.c failed'
- Wc_c="`wc -c < 'dmake/msdos/dirbrk.c'`"
- test 1785 -eq "$Wc_c" ||
- echo 'dmake/msdos/dirbrk.c: original size 1785, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/msdos/dirlib.h ==============
- if test -f 'dmake/msdos/dirlib.h' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/msdos/dirlib.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/msdos/dirlib.h' &&
- /* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89 */
- X
- #ifndef _DIRLIB_h_
- #define _DIRLIB_h_
- X
- #include <stdio.h>
- #include "stdmacs.h"
- X
- #define MAXNAMLEN 15
- X
- struct direct {
- X long d_ino;
- X unsigned short d_reclen;
- X unsigned short d_namlen;
- X char d_name[MAXNAMLEN+1];
- };
- X
- typedef struct {
- X char fcb[21];
- X char attr;
- X short time;
- X short date;
- X long size;
- X char name[13];
- } DTA;
- X
- typedef struct {
- X DTA dd_dta; /* disk transfer area for this dir. */
- X short dd_stat; /* status return from last lookup */
- X char dd_name[1]; /* full name of file -- struct is extended */
- } DIR;
- X
- extern DIR *opendir ANSI((char *));
- extern struct direct *readdir ANSI((DIR *));
- extern long telldir ANSI((DIR *));
- extern void seekdir ANSI((DIR *, long));
- extern void closedir ANSI((DIR *));
- extern DTA *findfirst ANSI((char *, DTA *));
- extern DTA *findnext ANSI((DTA *));
- X
- #define rewinddir(dirp) seekdir(dirp,0L)
- #endif
- SHAR_EOF
- chmod 0640 dmake/msdos/dirlib.h ||
- echo 'restore of dmake/msdos/dirlib.h failed'
- Wc_c="`wc -c < 'dmake/msdos/dirlib.h'`"
- test 1086 -eq "$Wc_c" ||
- echo 'dmake/msdos/dirlib.h: original size 1086, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= dmake/msdos/exec.asm ==============
- if test -f 'dmake/msdos/exec.asm' -a X"$1" != X"-c"; then
- echo 'x - skipping dmake/msdos/exec.asm (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- sed 's/^X//' << 'SHAR_EOF' > 'dmake/msdos/exec.asm' &&
- ;
- ; DESCRIPTION
- ; This code is a model independent version of DOS exec that will swap
- ; the calling process out to secondary storage prior to running the
- ; child. The prototype for calling the exec function is below.
- ;
- ; exec( int swap, char far *program, char far *cmdtail,
- ; int environment_seg, char far *tmpfilename );
- ;
- ;
- ; To assemble this file issue the command:
- ;
- ; tasm /mx /t /dmmodel exec.asm
- ;
- ; where 'model' is one of {small, compact, medium, large}, you may
- ; also use MASM 5.1 to assemble this file, in this case simply replace
- ; 'tasm' with 'masm' in the above command line.
- ;
- ; AUTHOR
- ; Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- ; CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- ;
- ; COPYRIGHT
- ; Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- ;
- ; This program is free software; you can redistribute it and/or
- ; modify it under the terms of the GNU General Public License
- ; (version 1), as published by the Free Software Foundation, and
- ; found in the file 'LICENSE' included with this distribution.
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warrant of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program; if not, write to the Free Software
- ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ;
- ifdef have286
- X .286 ; define have286 with -D for 80286 processor or better
- X mpusha Macro
- X pusha
- X Endm
- X
- X mpopa Macro
- X popa
- X Endm
- X
- else ; 8088/8086 compatible
- X mpusha Macro
- X push ax
- X push cx
- X push dx
- X push bx
- X push sp
- X push bp
- X push si
- X push di
- X Endm
- X
- X mpopa Macro
- X pop di
- X pop si
- X pop bp
- X add sp,2
- X pop bx
- X pop dx
- X pop cx
- X pop ax
- X Endm
- endif
- X
- ifdef msmall
- X .model small
- argbase equ 4
- endif
- ifdef mcompact
- X .model compact
- argbase equ 4
- endif
- ifdef mmedium
- X .model medium
- argbase equ 6
- endif
- ifdef mlarge
- X .model large
- argbase equ 6
- endif
- a_swap equ <bp+argbase+0>
- a_prog equ <bp+argbase+2>
- a_tail equ <bp+argbase+6>
- a_env equ <bp+argbase+10>
- a_tmp equ <bp+argbase+12>
- X
- a_handle equ <bp+argbase>
- X
- X
- ; Define all useful equ's
- swap_xms equ 0 ; we swapped it out to xms
- swap_ems equ 2 ; we swapped it out to ems
- swap_file equ 4 ; we swapped it out to a file
- seg_no_alloc equ 0 ; this is part of a segment
- seg_alloc equ 1 ; this is a full segment header
- seg_data equ 2 ; this is data for part of a segment
- X
- X
- ; Define any global/external variables that we will be accessing from here.
- X .data
- X extrn _errno:word ; Set to dos ret code from exec
- X public _Interrupted ; Set to 1 if interrupted 0
- _Interrupted dw 0 ; otherwise
- X
- X .code
- X assume cs:@code, ds:@code, ss:@code, es:@code
- X
- X even
- execstack dw 64 dup (?) ; put the temporary exec stack right
- exec_sp label word ; at the start.
- X
- old_ss dw ? ; save stack seg across exec
- old_sp dw ? ; save stack ptr across exec
- progsize dw ? ; original size of the program
- rootsize dw ? ; size of base root kept during swap
- resend dw ? ; paragraph where resident code ends
- envseg dw ? ; paragraph of environment segment
- psp dw ? ; our own psp
- swap dw ? ; swapping selection flag
- eretcode dw ? ; return code from exec
- interrupted dw ? ; interrupted flag for exec
- arenahead dw ? ; start of memory block list
- alstr dw ? ; allocation strategy save spot
- in_exec dw 0 ; flag, 1 ==> in exec
- X
- cmdpath db 65 dup(?) ; file to exec
- cmdtail db 129 dup(?) ; its command tail
- fcb db 37 dup(0) ; dummy fcb
- tmpseg db 7 dup(?) ; block header buffer
- X
- tmpname db 65 dup(0) ; name of temporary file resource
- X
- X even
- tmphandle dw ? ; handle for temporary file
- real_21h dd 0 ; will be DOS's 21h vector if doing -C
- X
- std_fil_handle dw ? ; file handle for -C file
- std_fil_number db ? ; system file number for -C file
- our_stdout db ? ; sys file number our stdout handle
- X
- error_rhdr db "exec: Failure reading header block", 0DH, 0AH, '$'
- error_rseg db "exec: Failure reading segment data", 0DH, 0AH, '$'
- error_resize db "exec: Failure on resize", 0DH, 0AH, '$'
- error_free db "exec: Failure to free a block", 0DH, 0AH, '$'
- error_string db "exec: Program swap failure", 0DH, 0AH, '$'
- error_alloc db "exec: Memory blocks don't match", 0DH, 0AH, '$'
- X
- X even
- write_header label word
- X whdr_xms_ptr dw word ptr whdr_xms
- X whdr_ems_ptr dw word ptr whdr_ems
- X whdr_file_ptr dw word ptr whdr_file
- X
- write_seg label word
- X wseg_xms_ptr dw word ptr wseg_xms
- X wseg_ems_ptr dw word ptr wseg_ems
- X wseg_file_ptr dw word ptr wseg_file
- X
- read_header label word
- X rhdr_xms_ptr dw word ptr rhdr_xms
- X rhdr_ems_ptr dw word ptr rhdr_ems
- X rhdr_file_ptr dw word ptr rhdr_file
- X
- read_seg label word
- X rseg_xms_ptr dw word ptr rseg_xms
- X rseg_ems_ptr dw word ptr rseg_ems
- X rseg_file_ptr dw word ptr rseg_file
- X
- free_resource label word
- X free_xms_ptr dw word ptr free_xms_resource
- X free_ems_ptr dw word ptr free_ems_resource
- X free_file_ptr dw word ptr free_file_resource
- X
- reset_resource label word
- X reset_xms_ptr dw word ptr reset_xms_resource
- X reset_ems_ptr dw word ptr reset_ems_resource
- X reset_file_ptr dw word ptr reset_file_resource
- X
- old_ctl_brk label dword
- X old_ctl_brk_off dw ?
- X old_ctl_brk_seg dw ?
- X
- old_crit_err label dword
- X old_crit_err_off dw ?
- X old_crit_err_seg dw ?
- X
- exec_block label word
- X ex_envseg dw ? ; env seg, use parent's if 0
- X ex_cmdtail dd ? ; command tail for exec
- X ex_fcb1 dd far ptr fcb ; fcb's aren't used by dmake
- X ex_fcb2 dd far ptr fcb
- X ex_ss dw ? ; saved ss for exec
- X ex_sp dw ? ; saved sp for exec
- X ex_error dw 0 ; error code for dos exec
- X
- X
- ; Special 21h (DOS call) handler to tee stdout/stderr writes to the -C file.
- ; Ignore 21h calls that aren't writes to 1 or 2; i.e., pass them to DOS handler.
- ; If write call was from this process, it's pretty simple to duplicate it
- ; to the -C file. If it's from another process, we try to write to its
- ; inherited handle. Worst case is where the handle wasn't inherited: someone
- ; closed it. In that instance we have to switch to dmake's PSP to do the
- ; duplicate write.
- X
- ; Subprocesses do not get their stdout/stderr teed to the -C file if
- ; their stdout/stderr no longer points to the file/device that dmake's
- ; stdout points to. This is tested by looking at the process's job
- ; file table, which is a table that maps process handles to DOS system file
- ; table numbers. (The far pointer to the JFT is at the PSP offset 34h.)
- ; The JFT is also queried to see if the -C file was inherited.
- X
- ; O_BINARY, O_TEXT problems are ignored here. These are fudged by the
- ; C library before it calls DOS; since we're working below that level
- ; we don't have to worry about it.
- X
- simulate_21h Macro
- X pushf ;; direct call to DOS
- X call cs:[real_21h]
- X Endm
- X
- X assume cs:@code, ds:nothing, es:nothing, ss:nothing
- our_21h_handler proc far
- X pushf
- X cmp ah,40h ; is this a write?
- X jne call_dos ; --no
- X cmp bx,1 ; write on handle 1 (stdout?)
- X je duplicate_it
- X cmp bx,2 ; stderr?
- X je duplicate_it
- X
- call_dos:
- X popf
- X jmp [real_21h] ; far jump to real handler, which will do the sys call
- X ; and return to the original caller
- X
- duplicate_it:
- X mpusha
- X push ds
- X push es
- X mov bp,sp
- X
- X mov di,std_fil_handle ; handle of the -C file
- X
- X If @codesize eq 0
- X ; Small/compact models allow for quick test of us versus subprocess.
- X ; False negative (it's us with a different CS) will be picked
- X ; up by code just below. (Might happen due to call from C library.)
- X ; False positives would be bad, but can't happen.
- X mov ax,[bp+24] ; caller's CS
- X cmp ax,@code ; same as us?
- X je call_from_dmake
- X Endif
- X
- X mov ah,51h ; get PSP ("undocumented version" works in DOS 2.0+)
- X simulate_21h ; PSP segment returned in BX
- X cmp bx,psp ; our PSP?
- X je call_from_dmake ; --yes, no PSP changing needed
- X
- X mov es,bx ; set ES to current (caller's) PSP
- X lds bx,es:[34h] ; set DS:BX pointing to caller's job file table
- X
- X mov si,[bp+12] ; file handle caller passed in (known to be 1 or 2)
- X mov al,[bx+si] ; system file number corresponding to caller's handle
- X cmp al,our_stdout ; same as our stdout?
- X jne do_real_write ; no--subprocess must have redirected it
- X
- X mov al,[bx+di] ; see if caller has dup of -C file still open
- X cmp al,std_fil_number
- X je use_dup ; yes--we can write using caller's PSP
- X
- X ; Calling process (or some intermediate process) has closed
- X ; the -C descriptor. We'll use dmake's (our) -C descriptor, but
- X ; to do so we'll have to change the PSP. Disable BREAK handling
- X ; so that ^break doesn't kill the wrong process.
- X
- X mov ax,3300h ; get BREAK flag
- X simulate_21h
- X mov si,dx ; save BREAK state in SI
- X sub dx,dx ; now turn break flag off
- X mov ax,3301h
- X simulate_21h ; don't want ^Break recoginized while PSP changed
- X mov bx,psp ; set dmake's PSP
- X mov ah,50h
- X simulate_21h
- X
- X mov bx,di ; handle of -C file
- X ; CX still has caller's count
- X mov ds,[bp+2] ; restore caller's DS
- X mov dx,[bp+14] ; DS:DX again points to caller's buffer
- X mov ah,40h
- X simulate_21h ; write the copy
- X
- X mov bx,es ; caller's PSP
- X mov ah,50h ; set PSP
- X simulate_21h ; restore caller's PSP
- X mov dx,si ; break state before we changed it
- X mov ax,3301h
- X simulate_21h ; restore break state
- X
- X jmp short do_real_write
- X
- use_dup:
- X mov ds,[bp+2] ; restore caller's DS
- X mov dx,[bp+14] ; DS:DX again points to caller's buffer
- X
- call_from_dmake:
- X mov bx,di ; handle of -C file
- X mov ah,40h ; write
- X ; CX still has caller's count
- X simulate_21h ; write to the file
- X
- do_real_write:
- X pop es
- X pop ds
- X mpopa
- X popf
- X jmp [real_21h] ; far jump to real handler, which will do the sys call
- X ; and return to the original caller
- our_21h_handler endp
- X
- X assume cs:@code, ds:@code, ss:@code, es:@code
- X
- ;-----------------------------------------------------------------------------
- ; First define the critical-error and control-brk handlers.
- ; The critical error handler simply pops the machine state and returns an
- ; access denied result code.
- crit_err_handler proc far
- X add sp, 6 ; ip/cs/flags ...
- X pop ax
- X pop bx
- X pop cx
- X pop dx
- X pop si
- X pop di
- X pop bp
- X pop ds
- X pop es
- X push bp ; fix up the return flags
- X mov bp, sp
- X xchg ax, [bp+6] ; get the flag byte.
- X or ax, 1 ; set the carry bit
- X xchg ax, [bp+6] ; put it back.
- X pop bp
- X mov ax, 5 ; access denied
- X iret
- crit_err_handler endp
- X
- X
- ;-----------------------------------------------------------------------------
- ; Here we set the interrupted flag, and terminate the currently running
- ; process.
- ctl_brk_handler proc far
- X clc ; make sure carry is clear
- X inc cs:interrupted ; set the flag
- X
- ; Make certain it isn't us that is going to get terminated.
- ; There is a small window where the in_exec flag is set but the child is
- ; not running yet, I assume that DOS doesn't test for ctl_brk at that time
- ; as it is bussily creating a new process.
- X cmp cs:in_exec,0
- X je just_return ; note this implies CF == 0
- X stc ; set CF to abort child
- just_return: iret
- ctl_brk_handler endp
- X
- X
- ;-----------------------------------------------------------------------------
- ; Something really nasty happened, so abort the exec call and exit.
- ; This kills the calling process altogether, and is a very nasty way of
- ; termination since files may still be open etc.
- abort_exec_rhdr label near
- X mov dx, offset error_rhdr
- X jmp print_it
- abort_exec_rseg label near
- X mov dx, offset error_rseg
- X jmp print_it
- abort_exec_resize label near
- X mov dx, offset error_resize
- X jmp print_it
- abort_exec_free label near
- X mov dx, offset error_free
- X jmp print_it
- abort_exec_alloc label near
- X mov dx, offset error_alloc
- X jmp print_it
- abort_exec proc near
- X mov dx, offset error_string
- print_it: push dx
- X mov bx, [swap]
- X call [free_resource+bx]
- X mov ax, cs
- X mov ds, ax
- X pop dx
- X mov ah, 9
- X int 21H
- kill_program: mov ax, 04cffH ; nuke it!
- X int 21H
- abort_exec endp
- X
- X
- ;-----------------------------------------------------------------------------
- ; lodsw/stosw loop to copy data. Called only for word copy operations.
- ; ds:si - point at source
- ; es:di - point at destination
- ; cx - count of bytes to copy.
- copy_data proc near
- X shr cx, 1 ; convert to word count
- X jnc copy_words
- X movsb
- copy_words: rep movsw ; copy the words.
- X ret
- copy_data endp
- X
- X
- X
- ;=============================================================================
- ; THE FOLLOWING SECTION DEALS WITH ALL ROUTINES REQUIRED TO READ XMS RECORDS.
- ;=============================================================================
- rhdr_xms proc near
- X ret
- rhdr_xms endp
- X
- rseg_xms proc near
- X ret
- rseg_xms endp
- X
- reset_xms_resource proc near
- X ret
- reset_xms_resource endp
- X
- free_xms_resource proc near
- X ret
- free_xms_resource endp
- ;=============================================================================
- X
- X
- X
- ;=============================================================================
- ; THE FOLLOWING SECTION DEALS WITH ALL ROUTINES REQUIRED TO READ EMS RECORDS.
- ;=============================================================================
- rhdr_ems proc near
- X ret
- rhdr_ems endp
- X
- rseg_ems proc near
- X ret
- rseg_ems endp
- X
- reset_ems_resource proc near
- X ret
- reset_ems_resource endp
- X
- free_ems_resource proc near
- X ret
- free_ems_resource endp
- ;=============================================================================
- X
- X
- X
- ;=============================================================================
- ; THE FOLLOWING SECTION DEALS WITH ALL ROUTINES REQUIRED TO READ FILE RECORDS.
- ;=============================================================================
- ; This routine reads a segment header from a file.
- ; The header is a seven byte record formatted as follows:
- ; segment address - of data
- ; offset address - of data
- ; length in paragraphs - of data
- ; mode - 1 => segment header (allocate seg on read)
- ; 0 => subsegment, don't allocate on read.
- ; The information is placed into the tmpseg data area in the code segment.
- ; The routine aborts if an error is detected.
- rhdr_file proc near
- X mov dx, offset tmpseg ; read the header record out
- X mov cx, 7
- X mov bx, [tmphandle]
- X mov ah, 03fH
- X int 21H
- X jnc rhdr_done ; make sure it worked
- X jmp abort_exec_rhdr
- X
- rhdr_done: cmp ax, 7
- X je exit_rhdr_file
- X or ax, ax
- X je signal_eof
- X jmp abort_exec_rhdr
- X
- signal_eof: stc
- exit_rhdr_file: ret
- rhdr_file endp
- X
- X
- ;-----------------------------------------------------------------------------
- ; Read a segment from the temporary file whose handle is in cs:tmphandle.
- ; The routine aborts if an error is detected.
- rseg_file proc near
- X push ds
- X mov ds, word ptr cs:tmpseg; Now read the whole segment
- X mov dx, word ptr cs:tmpseg+2
- X mov cx, word ptr cs:tmpseg+4
- X mov bx, cs:tmphandle
- X mov ah, 03fH
- X int 21H
- X pop ds
- X jnc rseg_done
- X jmp abort_exec_rseg
- X
- rseg_done: cmp ax, [word ptr tmpseg+4]
- X je exit_rseg_file
- X jmp abort_exec_rseg ; If we didn't get read full
- exit_rseg_file: ret ; segment then abort
- rseg_file endp
- X
- X
- ;-----------------------------------------------------------------------------
- ; Seek to the beginning of the file.
- reset_file_resource proc near
- X mov bx, [tmphandle]
- X xor cx, cx
- X mov dx, cx
- X mov ax, 04200H ; seek to begining of file
- X int 21H
- X ret
- reset_file_resource endp
- X
- X
- ;-----------------------------------------------------------------------------
- ; unlink the temporary file allocated for swapping.
- ; We close the file first, and then delete it. We ignore errors here since
- ; we can't do anything about them anyway.
- free_file_resource proc near
- X mov bx, [tmphandle] ; get the file handle
- X mov ah, 03eH ; close the file
- X int 21H
- X mov dx, offset tmpname ; Now delete the temp file
- X mov ah, 041H
- X int 21H
- X ret
- free_file_resource endp
- ;=============================================================================
- X
- X
- X
- ;=============================================================================
- ; CODE TO SWAP THE IMAGE IN FROM SECONDARY STORAGE
- ;=============================================================================
- swap_in proc near
- X mov bx, [alstr] ; get previous alloc strategy
- X mov ax, 5801H ; and set it back
- X int 21H
- X mov bx, [swap] ; get type of resource
- X call [reset_resource+bx] ; reset the resource
- X mov es, [psp] ; resize the program back
- X mov bx, [progsize] ; to original size
- X mov ah, 04AH
- X int 21H
- X jnc read_seg_loop
- X jmp abort_exec
- X
- read_seg_loop: mov bx, [swap] ; get type of resource
- X call [read_header+bx] ; get seg header
- X jc exit_swap_in ; all done
- X mov al, [tmpseg+6]
- X cmp al, seg_no_alloc ; see if dummy segment header
- X je read_seg_loop
- X cmp al, seg_alloc ; do we need to do an alloc?
- X jne read_data ; nope
- X
- ; Allocate back the memory for a segment that is not the [psp], note that this
- ; must come back to the same segment we had previously since other segments
- ; may have pointers stored in their variables that point to this segment using
- ; segment:offset long pointers.
- X mov bx, [word ptr tmpseg+4] ; get count of paragraphs
- X mov ah, 048H ; dos_alloc
- X int 21H
- X jc alloc_error ; oops!
- X cmp ax, [word ptr tmpseg] ; did we get the same segment?
- X je read_seg_loop ; yup!
- alloc_error: jmp abort_exec_alloc
- X
- read_data: mov bx, [swap]
- X call [read_seg+bx] ; this must succeed, if fail
- X jmp read_seg_loop ; we never come back here
- X
- exit_swap_in: mov bx, [swap] ; all done, so free resource
- X call [free_resource+bx]
- X ret
- swap_in endp
- X
- X
- ;=============================================================================
- ; CODE TO SWAP THE IMAGE OUT TO SECONDARY STORAGE
- ;=============================================================================
- ; This routine is called to swap the non-resident portion of the program
- ; out to the resource specified by the value of [cs:swap]. If the swap out
- ; fails, then appropriate routines are called to free the resources allocated
- ; up to that point.
- ;
- ; The steps used to swap the program out are as follows:
- ; - calculate new size of program to remain resident and size to swap
- ; out.
- ; - write out non-resident portion of current segment
- ; - walk DOS allocation chain and write out all other segments owned by
- ; the current program that are contiguous with the _psp segment
- ; - copy the environment down to low memory
- ; - resize the current _psp segment to savesize
- ; - free all segments belonging to program except current _psp segment
- swap_out proc near
- X mov ax, 05800H ; get memory alocation strategy
- X int 021H
- X mov [alstr], ax ; and save it for future restoration.
- X mov di, [psp] ; compute length of program to current
- X mov bx, cs ; value of cs, and find program size
- X sub bx, di ; by looking at length stored in
- X mov ax, di ; arena header found in front of psp
- X dec ax
- X mov es, ax
- X mov si, es:3 ; si is size of program in paragraphs
- X mov [progsize], si ; progsize now contains the size.
- X
- ; Now compute length of program segment to save.
- ; Length is: cs - psp + (offset overlay_code_here+15 >> 4)
- X mov ax, offset overlay_code_here+15
- X shr ax, 1
- X shr ax, 1
- X shr ax, 1
- X shr ax, 1
- X add bx, ax ; bx is size of program to keep
- X sub si, bx ; si is # of paragraphs to save.
- X add di, bx ; di is paragraph to start at
- X mov rootsize, bx
- X mov resend, di ; cs:resend is saved start para
- X mov al, seg_no_alloc ; set no allocation for segment
- SHAR_EOF
- true || echo 'restore of dmake/msdos/exec.asm failed'
- fi
- echo 'End of part 22, continue with part 23'
- echo 23 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
-